﻿#pragma once
#include "_private/_privateinc.h"
#include "logbase.h"
#include "../logger.h"
#include <tuple>
#include <array>
#include <map>
#include <assert.h>



NAMESPACE_BEG
struct FileHand {
    FileHand(FileHand&& ref) = delete;
    FileHand() {};
    FileHand& operator=(FileHand&& ref) {
        file_hand_ = ref.file_hand_;
        ref.file_hand_ = nullptr;
        level_ = ref.level_;
        path_ = std::move(ref.path_);
        write_cnt_ = ref.write_cnt_;
        file_name_ = std::move(ref.file_name_);
        return *this;
    }
    LOG_LEVEL      level_;
    std::string    file_name_;
    std::string    path_;
    std::ofstream* file_hand_ = nullptr;
    size_t         write_cnt_ = 0;
    ~FileHand() {
        if (file_hand_) {
            file_hand_->close();
            delete file_hand_;
        }
    }
};
using file_hands_t = std::map<LOG_LEVEL, FileHand*>;


class LoggerFilePrinter {
public:
    static LoggerFilePrinter& getInstance() {
        static LoggerFilePrinter printer;
        return printer;
    }
    ~LoggerFilePrinter();
    void print(const LogItem& logger);
    inline void setLogSaveDir(const std::string& dir, size_t max_size) {
        file_dir_ = dir;
    #ifdef WIN32
        std::for_each(file_dir_.begin(), file_dir_.end(), [](char& c) {if (c == '/') c = '\\'; });
    #endif
        file_max_size_ = max_size;
    }
    inline void setDisplayFormat(int format) { format_ = format; }
    inline void setDisplayValue(int value) { format_ = value; }
private:
    LoggerFilePrinter();
    void        __initFileHand();
    FileHand* __creatFilehand(LOG_LEVEL level, std::string file_name);
    void        __setLogFormat(const LogItem& logger);
    std::string __getToDaydDate();
private:
    int          format_ = 127;
    file_hands_t file_hands_;
    str_t        pos_str_;
    std::string  file_dir_ = "./log";
    size_t       file_max_size_ = 1024 * 1024 * 100;
    std::string  prefix_str_;
};

NAMESPACE_END
